updateProductHelper
- ๐ฌ๐ง English
- ๐ฎ๐น Italian
Function Name: updateExistingProductDocument
Author: Domenico Cerone Creation Date: 09/10/2025
Last Reviewer: Domenico Cerone
Trigger: Helper function (called by updateVariantProduct)
Purpose: Updates an existing document in the 'Products' Firestore collection using updated mapped JSON data. This function handles complete field refresh and tag regeneration while maintaining workflow fields unchanged.
Detailed Functionalityโ
This helper function performs comprehensive updates to existing Products documents with complete tag regeneration using thread-safe utilities.
1. EXISTING DOCUMENT LOADINGโ
- Receives
productRefas document ID parameter - Loads existing document from 'Products' collection
- If NOT EXISTS โ error (does not create new documents)
- If EXISTS โ proceeds with update (STEP 2)
2. FIELD UPDATES AND TAG REGENERATIONโ
- Updates only fields that come from mapped JSON
- COMPLETELY REGENERATES ALL TAGS (like populateVariantFromSku):
- Searches/creates tags in Tags collection using tagUtils
- Thread-safe to avoid duplicates
- Automatic translations (Gender โ Italian)
- AUTOMATIC BRAND NORMALIZATION: โข "HUGO" โ "HUGO EYEWEAR" โข "HUGO BOSS", "BOSS ORANGE" โ "BOSS EYEWEAR" โข "CARRERA BY JIMMYCHOO", "CARRERA BIKE", etc. โ "CARRERA" โข "POLAROID KIDS", "POLAROID STAYSAFE", etc. โ "POLAROID" โข "SMITH", "SMITH SNOW", "SUNCLOUD", etc. โ "SMITH OPTICS"
- Normalized brands for Line tags with correct catalogRef
- Maintains all existing workflow fields unchanged
- Maintains variants_map and list_variants existing
- Updates lastUpdate with current timestamp
Brand Normalization Systemโ
The function includes an intelligent brand normalization system that applies business rules to standardize brand names from SAP data to consistent marketing brand names.
Brand Mapping Rules:
- Hugo brands: "HUGO" โ "HUGO EYEWEAR"
- Boss brands: "HUGO BOSS", "BOSS ORANGE" โ "BOSS EYEWEAR"
- Carrera brands: "CARRERA BY JIMMYCHOO", "CARRERA BIKE", "CARRERA SNOW", "CARRERA DUCATI" โ "CARRERA"
- Polaroid brands: "POLAROID ANCILLARIES", "POLAROID KIDS", "POLAROID STAYSAFE" โ "POLAROID"
- Smith brands: "SMITH FASHION & ACC.", "SMITH BIKE HELMETS", "SMITH SNOW", "SMITH BIKE GOGGLES", "PRIVATE LABEL SMITH", "SUNCLOUD" โ "SMITH OPTICS"
- Other brands: Remain unchanged
Implementation: The mapToNormalizedBrand() function is called automatically during data mapping to ensure consistent brand naming across the Products collection.
Fields Updated from Mapped JSONโ
Base Product Fields:
ageโ catAgeForGendermanufacturedProductStatusโ manufacturedProductStatusrxAbleโ rxAble (converted from "YES"/"NO" to boolean)mainBrandRefโ brand ID (searches/creates in MainBrands collection)upcCodeโ upcCodeimgUrlโ poster (first image from current variant)thumbnailโ poster (first image from current variant)urlImageโ poster (first image from current variant)
Timestamp Fields:
lastUpdateโ current timestampproductReleaseDateโ productReleaseDate (if present)productEndDateโ productEndDate (if present)
Multilingual Descriptions:
descriptionEnโ description_endescriptionItโ description_itdescriptionEsโ description_esdescriptionFrโ description_frdescriptionDeโ description_de
Tags Arrays (regenerated from mapped JSON):
list_frame_color_tagsโ [frameColor tag IDs from Tags collection]list_size_tagsโ [size tag IDs from Tags collection]list_line_tagsโ [line tag IDs linked to normalized brand] INPUT: mappedData.mainBrandRef="HUGO BOSS", mappedData.nomeLinea="BOSS ORANGE SPORT" STEP 1: Search/create BRAND in MainBrands: "HUGO BOSS" โ normalize โ "BOSS EYEWEAR" โ brandId STEP 2: Search/create LINE TAG in Tags: name="BOSS ORANGE SPORT" + catalogRef=brandId OUTPUT: ["tag456def"] - Line tag ID linked to normalized brandlist_tagsโ [catType, catAgeForGender, catGender, catForma, catMaterialOne, polarised (as tag ID), catLensesTreat, hingeType]
Fields Maintained Unchangedโ
All other fields of the existing document remain unchanged:
modelName(primary identifier)variants_map(existing variant management)list_variants(existing variant IDs)availableVariants(existing count)- All workflow and configuration fields
Tag Creation Functionsโ
The function uses specialized thread-safe tag creation functions:
Frame Color Tags:
findOrCreateFrameColorTag()- Creates/finds tags with type "Frame Color"
Size Tags:
findOrCreateSizeTag()- Creates/finds tags with type "Size"
Line Tags:
findOrCreateLineTag()- Creates/finds tags with type "Line" and catalogRef to brand
Category Tags:
findOrCreateCatTypeTag()- Creates/finds "Tipologia" tagsfindOrCreateCatAgeForGenderTag()- Creates/finds "Age For Gender" tagsfindOrCreateCatGenderTag()- Creates/finds "Gender" tags with Italian translationfindOrCreateCatFormaTag()- Creates/finds "Forma" tagsfindOrCreateCatMaterialOneTag()- Creates/finds "Materiale" tagsfindOrCreatePolarisedTag()- Creates/finds "Polarised" tagsfindOrCreateCatLensesTreatTag()- Creates/finds "Treatement" tagsfindOrCreateHingeTypeTag()- Creates/finds "Hinge Type" tags
Input Parametersโ
Function Signature:
async function updateExistingProductDocument(productRef, mappedJsonData, requestId)
Parameters:
productRef(string, required): ID of the Products document to updatemappedJsonData(Object, required): Updated mapped JSON datarequestId(string, required): Request ID for logging
Expected mappedJsonData Structure:
This data comes from the main function after processing the CatalogOrder document and downloading/mapping fresh data from Safilo APIs:
{
"mapped_data": {
"catAgeForGender": "ADULT",
"manufacturedProductStatus": "ACTIVE",
"rxAble": "YES",
"mainBrandRef": "HUGO BOSS",
"upcCode": "762753916013",
"poster": "https://firebasestorage.googleapis.com/...",
"description_en": "Modern sunglasses",
"description_it": "Occhiali da sole moderni",
"frameColor": "BLACK",
"size": "54",
"nomeLinea": "BOSS ORANGE SPORT",
"catType": "SUNGLASSES FRAMES",
"catGender": "WOMAN",
"catForma": "ROUND",
"catMaterialOne": "ACETATE",
"polarised": "YES",
"catLensesTreat": "GRADIENT",
"hingeType": "FLEX",
"productReleaseDate": 1640995200000,
"productEndDate": 1672531200000
}
}
Output (Success)โ
{
"success": true,
"operation": "update",
"documentId": "existing_product_id",
"modelName": "BOSS 1234/S",
"message": "Documento Products aggiornato per ID existing_product_id",
"updatedFields": [
"age",
"manufacturedProductStatus",
"rxAble",
"mainBrandRef",
"upcCode",
"imgUrl",
"thumbnail",
"urlImage",
"lastUpdate",
"descriptionEn",
"descriptionIt",
"list_frame_color_tags",
"list_size_tags",
"list_line_tags",
"list_tags",
"productReleaseDate",
"productEndDate"
]
}
Output (Error)โ
{
"success": false,
"operation": "error",
"documentId": "existing_product_id",
"modelName": "UNKNOWN",
"message": "Errore nell'aggiornamento documento Products: Document not found",
"error": "Document not found"
}
Related Componentsโ
- Main Function: updateVariantProduct - Main function that calls this helper
- Variant Helper: updateVariantHelper - Parallel helper for Variants collection
- Tag Utilities: tagUtils - Thread-safe tag creation utilities with mutex synchronization to prevent duplicates
Error Handlingโ
The function includes comprehensive error handling:
- Document Not Found: Returns error if productRef doesn't exist
- Invalid Data: Validates mappedJsonData structure
- Tag Creation Errors: Continues operation even if some tags fail
- Firestore Errors: Catches and logs database operation errors
- Brand Creation Errors: Falls back to empty string if brand operations fail
Performance Considerationsโ
- Thread-Safe Operations: All tag operations use mutex synchronization
- Batch Tag Creation: Multiple tags created efficiently in parallel
- Minimal Database Writes: Only updates changed fields
- Error Isolation: Individual tag failures don't block document update
Function Name: updateExistingProductDocument
Autore: Domenico Cerone Data di creazione: 09/10/2025
Last Reviewer: Domenico Cerone
Trigger: Funzione helper (chiamata da updateVariantProduct)
Purpose: Aggiorna un documento esistente nella collezione 'Products' di Firestore usando dati JSON mappati aggiornati. Questa funzione gestisce il refresh completo dei campi e la rigenerazione dei tag mantenendo invariati i campi di workflow.
Funzionamento Dettagliatoโ
Questa funzione helper esegue aggiornamenti completi ai documenti Products esistenti con rigenerazione completa dei tag usando utilitร thread-safe.
1. CARICAMENTO DOCUMENTO ESISTENTEโ
- Riceve
productRefcome parametro ID documento - Carica documento esistente dalla collezione 'Products'
- Se NON ESISTE โ errore (non crea nuovi documenti)
- Se ESISTE โ procede con aggiornamento (STEP 2)
2. AGGIORNAMENTO CAMPI E RIGENERAZIONE TAGโ
- Aggiorna solo i campi che provengono dal JSON mappato
- RIGENERA COMPLETAMENTE TUTTI I TAG (come populateVariantFromSku):
- Cerca/crea tag nella collezione Tags usando tagUtils
- Thread-safe per evitare duplicati
- Traduzioni automatiche (Gender โ italiano)
- NORMALIZZAZIONE BRAND AUTOMATICA: โข "HUGO" โ "HUGO EYEWEAR" โข "HUGO BOSS", "BOSS ORANGE" โ "BOSS EYEWEAR" โข "CARRERA BY JIMMYCHOO", "CARRERA BIKE", etc. โ "CARRERA" โข "POLAROID KIDS", "POLAROID STAYSAFE", etc. โ "POLAROID" โข "SMITH", "SMITH SNOW", "SUNCLOUD", etc. โ "SMITH OPTICS"
- Brand normalizzati per tag Line con catalogRef corretto
- Mantiene tutti i campi di workflow esistenti invariati
- Mantiene variants_map e list_variants esistenti
- Aggiorna lastUpdate con timestamp corrente
Sistema Normalizzazione Brandโ
La funzione include un sistema intelligente di normalizzazione brand che applica regole di business per standardizzare i nomi brand dai dati SAP ai nomi brand marketing consistenti.
Regole Mappatura Brand:
- Brand Hugo: "HUGO" โ "HUGO EYEWEAR"
- Brand Boss: "HUGO BOSS", "BOSS ORANGE" โ "BOSS EYEWEAR"
- Brand Carrera: "CARRERA BY JIMMYCHOO", "CARRERA BIKE", "CARRERA SNOW", "CARRERA DUCATI" โ "CARRERA"
- Brand Polaroid: "POLAROID ANCILLARIES", "POLAROID KIDS", "POLAROID STAYSAFE" โ "POLAROID"
- Brand Smith: "SMITH FASHION & ACC.", "SMITH BIKE HELMETS", "SMITH SNOW", "SMITH BIKE GOGGLES", "PRIVATE LABEL SMITH", "SUNCLOUD" โ "SMITH OPTICS"
- Altri brand: Rimangono invariati
Implementazione: La funzione mapToNormalizedBrand() viene chiamata automaticamente durante il mapping dati per garantire nomenclatura brand consistente nella collezione Products.
Campi Aggiornati dal JSON Mappatoโ
Campi Base Prodotto:
ageโ catAgeForGendermanufacturedProductStatusโ manufacturedProductStatusrxAbleโ rxAble (convertito da "YES"/"NO" a boolean)mainBrandRefโ ID brand (cerca/crea nella collezione MainBrands)upcCodeโ upcCodeimgUrlโ poster (prima immagine dalla variante corrente)thumbnailโ poster (prima immagine dalla variante corrente)urlImageโ poster (prima immagine dalla variante corrente)
Campi Timestamp:
lastUpdateโ timestamp correnteproductReleaseDateโ productReleaseDate (se presente)productEndDateโ productEndDate (se presente)
Descrizioni Multilingua:
descriptionEnโ description_endescriptionItโ description_itdescriptionEsโ description_esdescriptionFrโ description_frdescriptionDeโ description_de
Array Tags (rigenerati dal JSON mappato):
list_frame_color_tagsโ [ID tag frameColor dalla collezione Tags]list_size_tagsโ [ID tag size dalla collezione Tags]list_line_tagsโ [ID tag line collegati al brand normalizzato] INPUT: mappedData.mainBrandRef="HUGO BOSS", mappedData.nomeLinea="BOSS ORANGE SPORT" STEP 1: Cerca/crea BRAND in MainBrands: "HUGO BOSS" โ normalizza โ "BOSS EYEWEAR" โ brandId STEP 2: Cerca/crea LINE TAG in Tags: name="BOSS ORANGE SPORT" + catalogRef=brandId OUTPUT: ["tag456def"] - ID tag line collegato al brand normalizzatolist_tagsโ [catType, catAgeForGender, catGender, catForma, catMaterialOne, polarised (come ID tag), catLensesTreat, hingeType]
Campi Mantenuti Invariatiโ
Tutti gli altri campi del documento esistente rimangono invariati:
modelName(identificatore principale)variants_map(gestione varianti esistente)list_variants(ID varianti esistenti)availableVariants(conteggio esistente)- Tutti i campi di workflow e configurazione
Funzioni Creazione Tagโ
La funzione usa funzioni specializzate thread-safe per la creazione tag:
Tag Frame Color:
findOrCreateFrameColorTag()- Crea/trova tag con tipo "Frame Color"
Tag Size:
findOrCreateSizeTag()- Crea/trova tag con tipo "Size"
Tag Line:
findOrCreateLineTag()- Crea/trova tag con tipo "Line" e catalogRef al brand
Tag Categoria:
findOrCreateCatTypeTag()- Crea/trova tag "Tipologia"findOrCreateCatAgeForGenderTag()- Crea/trova tag "Age For Gender"findOrCreateCatGenderTag()- Crea/trova tag "Gender" con traduzione italianafindOrCreateCatFormaTag()- Crea/trova tag "Forma"findOrCreateCatMaterialOneTag()- Crea/trova tag "Materiale"findOrCreatePolarisedTag()- Crea/trova tag "Polarised"findOrCreateCatLensesTreatTag()- Crea/trova tag "Treatement"findOrCreateHingeTypeTag()- Crea/trova tag "Hinge Type"
Parametri Inputโ
Firma Funzione:
async function updateExistingProductDocument(productRef, mappedJsonData, requestId)
Parametri:
productRef(string, richiesto): ID del documento Products da aggiornaremappedJsonData(Object, richiesto): Dati JSON mappati aggiornatirequestId(string, richiesto): ID richiesta per logging
Struttura mappedJsonData Attesa:
Questi dati provengono dalla funzione principale dopo aver processato il documento CatalogOrder e scaricato/mappato dati aggiornati dalle API Safilo:
{
"mapped_data": {
"catAgeForGender": "ADULT",
"manufacturedProductStatus": "ACTIVE",
"rxAble": "YES",
"mainBrandRef": "HUGO BOSS",
"upcCode": "762753916013",
"poster": "https://firebasestorage.googleapis.com/...",
"description_en": "Modern sunglasses",
"description_it": "Occhiali da sole moderni",
"frameColor": "BLACK",
"size": "54",
"nomeLinea": "BOSS ORANGE SPORT",
"catType": "SUNGLASSES FRAMES",
"catGender": "WOMAN",
"catForma": "ROUND",
"catMaterialOne": "ACETATE",
"polarised": "YES",
"catLensesTreat": "GRADIENT",
"hingeType": "FLEX",
"productReleaseDate": 1640995200000,
"productEndDate": 1672531200000
}
}
Output (Successo)โ
{
"success": true,
"operation": "update",
"documentId": "id_product_esistente",
"modelName": "BOSS 1234/S",
"message": "Documento Products aggiornato per ID id_product_esistente",
"updatedFields": [
"age",
"manufacturedProductStatus",
"rxAble",
"mainBrandRef",
"upcCode",
"imgUrl",
"thumbnail",
"urlImage",
"lastUpdate",
"descriptionEn",
"descriptionIt",
"list_frame_color_tags",
"list_size_tags",
"list_line_tags",
"list_tags",
"productReleaseDate",
"productEndDate"
]
}
Output (Errore)โ
{
"success": false,
"operation": "error",
"documentId": "id_product_esistente",
"modelName": "UNKNOWN",
"message": "Errore nell'aggiornamento documento Products: Document not found",
"error": "Document not found"
}
Componenti Correlatiโ
- Funzione Principale: updateVariantProduct - Funzione principale che chiama questo helper
- Helper Variant: updateVariantHelper - Helper parallelo per collezione Variants
- Utilitร Tag: tagUtils - Utilitร creazione tag thread-safe con sincronizzazione mutex per prevenire duplicati
Gestione Erroriโ
La funzione include gestione errori completa:
- Documento Non Trovato: Restituisce errore se productRef non esiste
- Dati Invalidi: Valida struttura mappedJsonData
- Errori Creazione Tag: Continua operazione anche se alcuni tag falliscono
- Errori Firestore: Cattura e logga errori operazioni database
- Errori Creazione Brand: Fallback a stringa vuota se operazioni brand falliscono
Considerazioni Performanceโ
- Operazioni Thread-Safe: Tutte le operazioni tag usano sincronizzazione mutex
- Creazione Tag Batch: Piรน tag creati efficientemente in parallelo
- Scritture Database Minimali: Aggiorna solo campi modificati
- Isolamento Errori: Fallimenti tag individuali non bloccano aggiornamento documento